#include "main.h"
#include "rs485.h"
#include "usart.h"


uint8_t _485_CMDSend[_485_CMD_SIZE];
uint8_t _485_CMDRecv[_485_CMD_SIZE];

uint8_t _485_GenCheckCode(uint8_t *cmd, int start, int end){
    uint8_t ans = 0;
    for(int i=start; i<=end; i++)
        ans+=cmd[i];
    return ans;
}

uint8_t _485_CheckRecv(){
    // 校验接收到的数据
    if(_485_CMDRecv[0] == 0xE0 && _485_CMDRecv[1]!=0){
        if (_485_GenCheckCode(_485_CMDRecv, 1, _485_CMDRecv[1]-1) != _485_CMDRecv[_485_CMDRecv[1]]) {
            return 1;  // 数据有问题
        }
    }
    return 0;  // 数据没问题
}

void _485_SendCmd(uint8_t *cmd, int len){
    HAL_GPIO_WritePin(U3_485DIR_GPIO_Port, U3_485DIR_Pin, GPIO_PIN_SET);  // 允许发送
    HAL_Delay(1);
    HAL_UART_Transmit(&huart3, cmd, len, 100);
    HAL_GPIO_WritePin(U3_485DIR_GPIO_Port, U3_485DIR_Pin, GPIO_PIN_RESET);  // 允许接收
}
void _485_HandShake()
{
    _485_CMDSend[0] = 0xE0;
    _485_CMDSend[1] = 0x03;
    _485_CMDSend[2] = 0xA0;
    _485_CMDSend[_485_CMDSend[1]] = _485_GenCheckCode(_485_CMDSend, 1, _485_CMDSend[1] - 1);
    _485_SendCmd(_485_CMDSend, _485_CMDSend[1] + 1);
}

void _485_GetAttitudeAngle(){
    _485_CMDSend[0] = 0xE0;
    _485_CMDSend[1] = 0x03;
    _485_CMDSend[2] = 0x01;
    _485_CMDSend[_485_CMDSend[1]] = _485_GenCheckCode(_485_CMDSend, 1, _485_CMDSend[1]-1);
    _485_SendCmd(_485_CMDSend, _485_CMDSend[1]+1);
}

void _485_SetMagneticAngle(float angle){
    _485_CMDSend[0] = 0xE0;
    _485_CMDSend[1] = 0x05;
    _485_CMDSend[2] = 0x31;
    _485_CMDSend[3] = (angle>0?0:0x10) | ((int)angle/10);
    _485_CMDSend[4] = (((int)angle % 10) << 4) | ((int)(angle * 10)%10);
    _485_CMDSend[_485_CMDSend[1]] = _485_GenCheckCode(_485_CMDSend, 1, _485_CMDSend[1]-1);
    _485_SendCmd(_485_CMDSend, _485_CMDSend[1]+1);

}

void _485_GetMagneticAngle(){
    _485_CMDSend[0] = 0xE0;
    _485_CMDSend[1] = 0x03;
    _485_CMDSend[2] = 0x02;
    _485_CMDSend[_485_CMDSend[1]] = _485_GenCheckCode(_485_CMDSend, 1, _485_CMDSend[1]-1);
    _485_SendCmd(_485_CMDSend, _485_CMDSend[1]+1);
}

// 发送校准dcm命令
void _485_CorrectDcm(){
    _485_CMDSend[0] = 0xE0;
    _485_CMDSend[1] = 0x03;
    _485_CMDSend[2] = 0x32;
    _485_CMDSend[_485_CMDSend[1]] = _485_GenCheckCode(_485_CMDSend, 1, _485_CMDSend[1]-1);
    _485_SendCmd(_485_CMDSend, _485_CMDSend[1]+1);
}

// 保存dcm校准命令
void _485_SaveCorrectDCMCmd(){
    _485_CMDSend[0] = 0xE0;
    _485_CMDSend[1] = 0x03;
    _485_CMDSend[2] = 0x33;
    _485_CMDSend[_485_CMDSend[1]] = _485_GenCheckCode(_485_CMDSend, 1, _485_CMDSend[1]-1);
    _485_SendCmd(_485_CMDSend, _485_CMDSend[1]+1);
}

// 设置dcm波特率命令
void _485_SetDcmBaud(uint8_t b){
    if(b>=6) return;

    uint16_t bauds[]={2400, 4800, 9600, 19200, 38400, 115200};
    _485_CMDSend[0] = 0xE0;
    _485_CMDSend[1] = 0x04;
    _485_CMDSend[2] = 0x34;
    _485_CMDSend[3] = bauds[b];
    _485_CMDSend[_485_CMDSend[1]] = _485_GenCheckCode(_485_CMDSend, 1, _485_CMDSend[1]-1);
    _485_SendCmd(_485_CMDSend, _485_CMDSend[1]+1);
}


// 设置dcm角度输出模式：0问答式输出， 1自动输出
void _485_SetDcmOutputMode(uint8_t m){
    if(m>=2) return;
    _485_CMDSend[0] = 0xE0;
    _485_CMDSend[1] = 0x04;
    _485_CMDSend[2] = 0x35;
    _485_CMDSend[3] = m;
    _485_CMDSend[_485_CMDSend[1]] = _485_GenCheckCode(_485_CMDSend, 1, _485_CMDSend[1]-1);
    _485_SendCmd(_485_CMDSend, _485_CMDSend[1]+1);
}

// 获取plug压力值
void _485_GetPlugPressure(){
    _485_CMDSend[0] = 0xE0;
    _485_CMDSend[1] = 0x03;
    _485_CMDSend[2] = 0x71;
    _485_CMDSend[_485_CMDSend[1]] = _485_GenCheckCode(_485_CMDSend, 1, _485_CMDSend[1]-1);
    _485_SendCmd(_485_CMDSend, _485_CMDSend[1]+1);
}

// z: 00采集一次压力值后设置为零点参考值，01直接开启调零模式，02关闭调零模式
void _485_SetPlugZero(uint8_t z){
    if(z>=3) return;
    _485_CMDSend[0] = 0xE0;
    _485_CMDSend[1] = 0x04;
    _485_CMDSend[2] = 0x91;
    _485_CMDSend[3] = z;
    _485_CMDSend[_485_CMDSend[1]] = _485_GenCheckCode(_485_CMDSend, 1, _485_CMDSend[1]-1);
    _485_SendCmd(_485_CMDSend, _485_CMDSend[1]+1);
}

// 设置plug为待机模式（一问一答）
void _485_SetPlugStop(){
    _485_CMDSend[0] = 0xE0;
    _485_CMDSend[1] = 0x03;
    _485_CMDSend[2] = 0x92;
    _485_CMDSend[_485_CMDSend[1]] = _485_GenCheckCode(_485_CMDSend, 1, _485_CMDSend[1]-1);
    _485_SendCmd(_485_CMDSend, _485_CMDSend[1]+1);
}




